<?php
/**
 * User: @lixu
 * Date: 2019-03-27
 * Time: 17:23
 */

namespace Biz\service;

use Biz\cache\Coupon as cCoupon;
use Biz\cache\GoodsHistory as cGoodsHistory;
use Biz\model\activity\CouponConfig;
use Biz\model\GoodsBasicInfo as mGoodsBasicInfo;
use Biz\model\ShopCarouselBanner;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\module\Packages\Recommend\RecommendGoods;
use Biz\service\CarouselBanner as sCarouselBanner;
use Biz\service\esSearch\Goods as esGoods;
use Biz\service\Goods as sGoods;
use Biz\service\search\Brand;
use Doraemon\service\MultiContent\MultiContent;
use Doraemon\tools\HhzClient;
/**
 * @deprecated
 */
class SearchGoods
{
    const DEFAULT_PAGE_SIZE = 30;

    /**
     * 商城tab顶部根据关键词搜索
     * @param $keywords
     * @param $sort
     * @param $areaCode
     * @param $uid
     * @param $page
     * @param int $pageSize
     * @return array
     */
    public static function searchGoodsByMallTab($keywords, $sort, $areaCode, $uid, $page, $pageSize = self::DEFAULT_PAGE_SIZE)
    {
        $result = [
            'list' => [],
            'recommed_list' => [],
            'is_over' => 1,
        ];

        $startNum = ($page - 1) * $pageSize;

        $BrandRst = Brand::searchByFields(['brand_alias' => array_filter(explode(' ', $keywords))]);
        $brandId = $BrandRst['rows'] ? array_column($BrandRst['rows'], 'id') : [];

        $where = array_filter([
            'brand_id' => $brandId,
            'title' => $keywords,
            'material' => $keywords,
            'style' => $keywords,
            'category_name' => $keywords,
            'source' => esGoods::SOURCE_APP
        ]);


        // 根据关键词查询es， 查询不到的话， 最后会返回用户浏览过却没有买过的商品
        $searchResult = self::searchEntrance($where, esGoods::SCENES_MALL_TAB, $sort, $page, $pageSize);

        if ($searchResult['total']) {
            $goodsList = sGoods::Goods($searchResult['rows'], sGoods::FIELDS_GROUP_LIST, ['area_code' => $areaCode]);
            $goodsList = array_values($goodsList);
            if (version_compare(HhzClient::getClientVersion(), "3.9.0", ">=")) {
                $result['list'] = self::formatSearchResults($uid, $goodsList, $keywords, $page, $pageSize);
            } else {
            }
        }

        $result['is_over'] = $searchResult['is_over'];

        return $result;

    }

    /**
     * 商家店铺主页顶部根据关键词搜索
     * @param $keywords
     * @param $shopId
     * @param $sort
     * @param $areaCode
     * @param $page
     * @param int $pageSize
     * @return array
     * @throws \Exception
     */
    public static function searchGoodsByShopTab($keywords, $shopId, $sort, $areaCode, $page, $pageSize = self::DEFAULT_PAGE_SIZE)
    {
        $BrandUserType = BrandUser::getBrandUserType($shopId);
        $result = [
            'list' => [],
            'is_over' => 1,
        ];
        if ($BrandUserType == BrandUser::BRAND_USER_TYPE_A) {
            throw new \Exception('A类品牌没有商品');
        } else if ($BrandUserType == BrandUser::BRAND_USER_TYPE_B || $BrandUserType == BrandUser::BRAND_USER_TYPE_C) {
            $where = [
                'shop_id' => $shopId,
            ];
        } else if ($BrandUserType == BrandUser::BRAND_USER_TYPE_D) {
            $where = [
                'brand_id' => BrandUser::getUserBrandId($shopId),
            ];
        } else {
            return $result;
        }


        $where = array_merge($where, [
            'title' => $keywords,
            'material' => $keywords,
            'style' => $keywords,
            'category_name' => $keywords,
            'source' => esGoods::SOURCE_APP
        ]);

        $results = self::searchEntrance($where, esGoods::SCENES_SHOP_TAB, $sort, $page, $pageSize);
        if ($results['total']) {
            $result['list'] = sGoods::Goods($results['rows'], sGoods::FIELDS_GROUP_LIST, ['area_code' => $areaCode]);;
            $result['list'] = array_values($result['list']);
            $result['is_over'] = $results['is_over'];
        }

        return $result;
    }

    /**
     * 根据商品TAG取商品
     * @param $tagName
     * @param $sortType
     * @param int $page
     * @param int $pageSize
     * @param array $params
     * @param array $field
     * @return array
     */
    public static function searchGoodsByTag($tagName, $sortType, $page = 1, $pageSize = self::DEFAULT_PAGE_SIZE, $params = [], $field = ['id'])
    {

        $params = ShopClassify::verifyParams($params);

        $where = array_filter([
            'min_price_has_stock' => isset($params['price_range'][0]) ? $params['price_range'][0] : 0,
            'max_price_has_stock' => isset($params['price_range'][1]) ? $params['price_range'][1] : 0,
            'brand_id' => isset($params['brand']) ? $params['brand'] : [],
            'tags_content' => $tagName,
            'source' => esGoods::SOURCE_APP
        ]);


        $result = self::searchEntrance($where, esGoods::SCENES_GOODS_TAG, $sortType, $page, $pageSize, $field);

        return $result;
    }

    /**
     * 根据品牌id 与 类目id 交集 取maxCounter个商品id
     * @param $brandIds
     * @param $cateIds
     * @param $pageSize
     * @param $notGIds
     * @return array
     */
    public static function searchGoodsIdsByBrandIdsAndCateIds($brandIds, $cateIds, $pageSize, $notGIds)
    {
        $rstGoodsIds = [];
        $brandIds = array_unique($brandIds);
        $cateIds = array_unique($cateIds);
        foreach ($brandIds as $brandId) {
            foreach ($cateIds as $cateId) {
                if (count($rstGoodsIds) < $pageSize) {
                    $where['brand_id'] = $brandId;
                    $where['last_category_id'] = $cateId;
                    $where['source'] = esGoods::SOURCE_APP;
                    if ($notGIds) {
                        $where['id[!]'] = $notGIds;
                    }
                    $where['ORDER'] = self::randomSort();
                    $result = self::searchEntrance($where, esGoods::SCENES_BRAND_CATEGORY, 0, 1, 3); //每个
                    $goodsIds = $result['rows'];

                    $notGIds = array_merge($notGIds, $goodsIds);
                    $rstGoodsIds = array_merge($rstGoodsIds, $goodsIds);
                } else {
                    break;
                }
            }
        }
        return $rstGoodsIds;
    }

    /**
     * 根据品牌id 与 类目名称 交集 取maxCounter个商品id
     * @param $cateNames
     * @param $BrandIds
     * @param $maxCounter
     * @param $notGids
     * @return array
     */
    public static function searchGoodsIdsByCateNamesAndBrandIds($cateNames, $BrandIds, $maxCounter, $notGids)
    {
        $goodsIds = [];
        if ($cateNames) {
            if ($BrandIds) {
                $goodsIds = self::searchGoodsIdsByCateNames($cateNames, $maxCounter, $notGids, ['brand_id' => $BrandIds]);
            }
            if (count($goodsIds) < $maxCounter) {
                $maxCounter = $maxCounter - count($goodsIds);
                $goodsIds = array_merge($goodsIds,
                    self::searchGoodsIdsByCateNames($cateNames, $maxCounter, $goodsIds)
                );
            }
            if (count($goodsIds) < $maxCounter) {
                $maxCounter = $maxCounter - count($goodsIds);
                $goodsIds = array_merge($goodsIds,
                    self::searchGoodsIdsBySameLevelCateNames($cateNames, $maxCounter, $goodsIds)
                );
            }
        }
        return $goodsIds;
    }

    private static function searchGoodsIdsByCateNames($cateNames, $maxCounter, $notGids, $where = [])
    {
        $goodsIds = [];
        foreach ($cateNames as $cateName) {
            $where = [
                'last_category_name' => $cateName,
                'id[!]' => $notGids,
                'ORDER' => self::randomSort(),
                'source' => esGoods::SOURCE_APP
            ];
            $result = self::searchEntrance($where, esGoods::SCENES_LAST_CATEGORY_NAME, 0, 1, 3);
            $goodsIds = $result['rows'];
            $notGids = array_merge($notGids, $goodsIds);
        }
        return $goodsIds;
    }

    private static function searchGoodsIdsBySameLevelCateNames($cateNames, $maxCounter, $notGids, $searchField = 'third_category_name')
    {
        $findFieldMap = [
            'third_category_name' => 'second_category_id',
            'four_category_name' => 'four_category_id',
        ];
        $results = self::searchEntrance([$searchField => $cateNames, 'source' => esGoods::SOURCE_APP], esGoods::SCENES_LEVEL_CATEGORY_NAME, 0, 1, count($cateNames), [$findFieldMap[$searchField]]);
        $parentCateIds = $results['rows'];
        $goodsIds = [];
        $parentCateIds = array_unique($parentCateIds);
        foreach ($parentCateIds as $parentCateId) {
            if (count($goodsIds) < $maxCounter) {
                $where = [
                    $findFieldMap[$searchField] => $parentCateId,
                    'id[!]' => $notGids,
                    'ORDER' => self::randomSort(),
                    'source' => esGoods::SOURCE_APP,
                ];
                $results = self::searchEntrance($where, esGoods::SCENES_LEVEL_CATEGORY_NAME, 0, 1, 3);
                $goodsIds = array_merge($goodsIds, $results['rows']);
                $notGids = array_merge($notGids, array_column($results['rows'], 'id'));
            }
        }
        if (count($goodsIds) < $maxCounter && $searchField != 'four_category_name') {
            $goodsIds = array_merge($goodsIds,
                self::searchGoodsIdsBySameLevelCateNames($cateNames, $maxCounter - count($goodsIds), $notGids, 'four_category_name')
            );
        }
        return $goodsIds;
    }

    /**
     * 商品详情底部推荐商品列表
     * @param $goodsId
     * @param $shopId
     * @param $categoryIds
     * @param int $maxCount
     * @return array
     */
    public static function recommendGoods($goodsId, $shopId, $categoryIds, $maxCount = 20)
    {
        $where = [
            'category_id' => $categoryIds,
            'shop_id' => $shopId,
            'id[!]' => $goodsId,
            'app_status' => mGoodsBasicInfo::$statusAppNormalMap,
            'ORDER' => [
                'four_category_id' => 'DESC',
                'third_category_id' => 'DESC',
                'second_category_id' => 'DESC',
                'category_id' => 'DESC'
            ],
            'source' => esGoods::SOURCE_APP
        ];

        $result = self::searchEntrance($where, esGoods::SCENES_GOODS_RECOMMEND, 0, 1, $maxCount);
        $goodsIds = $result['rows'];

        if (count($goodsIds) < $maxCount) {
            $where = [];
            $where['shop_id'] = $shopId;
            $where['id[!]'] = array_merge($goodsIds, [$goodsId]);
            $where['source'] = esGoods::SOURCE_APP;
            $result = self::searchEntrance($where, esGoods::SCENES_GOODS_RECOMMEND, 0, 1, $maxCount - count($goodsIds));
            $otherGoodsIds = $result['rows'];
            shuffle($otherGoodsIds);
            $goodsIds = array_merge($goodsIds, $otherGoodsIds);
        }

        return $goodsIds;
    }

    /**
     * 优惠券凑单列表
     * @param $classifyIds
     * @param $minPrice
     * @param $maxPrice
     * @param $couponIf
     * @param $sortType
     * @param $page
     * @return array
     * @throws \Exception
     */
    public static function searchGoodsByClassifies($classifyIds, $minPrice, $maxPrice, $couponIf, $sortType, $page)
    {
        $where = [];
        $cateIds = [];
        foreach ($classifyIds as $classifyId) {
            $classifyInfo = Category::getCateIdsByClassifyId($classifyId);
            $cateIds = array_merge($cateIds, $classifyInfo['cate_ids']);
        }
        $where['category_id'] = $cateIds;
        $couponConfig = cCoupon::getConfig($couponIf); // 查看优惠券是否存在 $couponIf = 优惠券id
        if (!$couponConfig) {
            throw new \Exception('优惠券不存在');
        }
        if ($couponConfig['assume'] && $couponConfig['assume'] == CouponConfig::COUPON_ASSUME_SHOP) { // assume = 承担方
            $where['shop_id'] = $couponConfig['shop_id'];
        }
        if ($couponConfig['cate_scope'] == CouponConfig::CATE_SCOPE_NOT_ALL) {
            $tmpCates = array_filter(explode('|', $couponConfig['cate_ids']));
            foreach ($tmpCates as $cate) {
                $where['category_id'] = array_merge($where['AND']['category_id'], array_filter(explode('-', $cate)));
            }
        }
        if ($couponConfig['include_goods_ids']) {
            $where['id'] = array_filter(explode(',', $couponConfig['include_goods_ids']));
        }

        if ($minPrice && $maxPrice) {
            $where['min_price_has_stock'] = $minPrice;
            $where['max_price_has_stock'] = $maxPrice;
        } else if ($minPrice) {
            $where['min_price_has_stock'] = $minPrice;
        } else if ($maxPrice) {
            $where['max_price_has_stock'] = $maxPrice;
        }

        $where['source'] = esGoods::SOURCE_APP;
        $results = self::searchEntrance($where, esGoods::SCENES_COUPON_POLYMERIZATION, $sortType, $page);
        $results = isset($results['rows']) ? $results : [];
        return $results;
    }

    public static function searchEntrance($where = [], $scenes = null, $sortType = 0, $page = 1, $pageSize = 20, $field = ['id'])
    {
        $result = esGoods::getList($where, $scenes, $sortType, $page, $pageSize, $field);
        return $result;
    }

    /**
     * 处理搜索结果 在搜索结果中嵌套banner
     * @param $uid
     * @param $goodsList
     * @param $keywords
     * @param $page
     * @param $pagesize
     * @return array
     */
    private static function formatSearchResults($uid, $goodsList, $keywords, $page, $pagesize)
    {
        $result = [];
        $carouseBanners = sCarouselBanner::getMultipleBanner($uid, date("Y-m-d H:i:s"));
        $carouseBanners = array_column($carouseBanners, null, 'type');
        $carouseBanner = $carouseBanners[1028];
        $carouseBanner = self::filterCarouseBanner($keywords, $carouseBanner, $page, $pagesize);
        foreach ($goodsList as $k => $item) {
            $result[] = [
                'type' => RecommendGoods::GOODS_TYPE,
                'goods_info' => $item,
                'stat_info' => MultiContent::getSearchStat($page, $pagesize * $page + ($k + 1), $uid, MultiContent::CONTENT_FROM_SEARCH)
            ];
            if ($carouseBanner['search_results'] && ($k + 1) % 2 == 0) {
                $banner = array_shift($carouseBanner['search_results']);
                $result[] = [
                    'type' => ShopCarouselBanner::TYPE_APP_BANNER_INFO,
                    'banner_info' => $banner
                ];
            }
        }
        return $result;
    }

    /**
     * 过滤banner
     * @param $keywords
     * @param $carouseBanner
     * @param $page
     * @param $pagesize
     * @return mixed
     */
    private static function filterCarouseBanner($keywords, $carouseBanner, $page, $pagesize)
    {
        // 将 关键字 转换为数组
        $keywords = explode(' ', $keywords);
        $searchResult = [];
        if (isset($carouseBanner['search_results']) && $carouseBanner['search_results']) {
            foreach ($carouseBanner['search_results'] as $item) {
                // 将tag转换为数组
                // 如果 关键字和tag有交集的话，返回banner
                if (array_intersect(explode(',', $item['banner_desc']), $keywords)) {
                    $searchResult[] = $item;
                }
            }
        }

        if (isset($searchResult[($page - 1) * $pagesize / 4])) {
            $searchResult = array_slice($searchResult, ($page - 1) * $pagesize / 4, $pagesize / 4); //防止每页的banner重复  所以 截取
        } else {
            $searchResult = [];
        }
        $carouseBanner['search_results'] = $searchResult;
        return $carouseBanner;
    }

    /**
     * 返回用户浏览过却没有买过的商品
     * @return array
     */
    private static function browseHistoryWithoutBought()
    {
        $zsetKey = cGoodsHistory::getBrowseKey(HhzClient::getUid());
        $goodsIds = cGoodsHistory::zrevrange($zsetKey, 0, -1, 'withscores');
        $goodsIds = array_keys($goodsIds);
        $goodsIds = array_diff($goodsIds, array_keys(
            mOrderGoods::getUserBoughtGoodsIds(HhzClient::getUid())
        ));

        return array_filter($goodsIds);
    }

    /**
     * 2018双十一附加信息
     * @return bool
     */
    public static function isInDouble11()
    {
        $startTime = strtotime('2018-11-01');
        $endTime = strtotime('2018-11-16');
        if ($startTime < time() && $endTime > time()) {
            return true;
        }
        return false;
    }

    public static function randomSort()
    {
        $fields = [
            'id',
            'stock',
            'sell_total',
            'min_price',
            'max_price',
            'min_price_has_stock',
            'max_price_has_stock',
            'addtime',
            'operate_time',
            'first_online_time',
            'heat_degree'
        ];

        return [$fields[array_rand($fields)] => 'DESC'];
    }
}